package Words.Utils;



import Words.Mapper.WordMapper;
import Words.Pojo.Word;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.junit.jupiter.api.Test;

import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import java.io.*;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

public class MybatisUtils {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    WordMapper wordMapper = sqlSession.getMapper(WordMapper.class);
    static SqlSessionFactory sqlSessionFactory = null;

    static {
        try {
            //使用Mybatis第一步：获取SqlSessionFactory
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
//            e.printStackTrace();
            System.out.println("110");
        }
    }

    //既然有了SqlSessionFactory，顾名思义，我们需要获得SqlSession的实例
    //SqlSession 提供了在数据库执行SQL命令所需的所有方法
    public static SqlSession getSqlSession() {
        return sqlSessionFactory.openSession(true);
    }

    public static byte[] serialize(List<List<byte[]>> object) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(object);
        objectOutputStream.close();
        return byteArrayOutputStream.toByteArray();
    }
    public static List<List<byte[]>> deserialize(byte[] data) throws IOException, ClassNotFoundException {
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data);
        ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
        return (List<List<byte[]>>) objectInputStream.readObject();
    }
    public static byte[] convertListToByteArray(List<byte[]> byteList) throws IOException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        for (byte[] bytes : byteList) {
            outputStream.write(bytes);
        }
        return outputStream.toByteArray();
    }

    public static List<byte[]> convertByteArrayToList(byte[] byteArray, int arraySize) {
        List<byte[]> resultList = new ArrayList<>();
        for (int i = 0; i < byteArray.length; i += arraySize) {
            byte[] subArray = new byte[arraySize];
            System.arraycopy(byteArray, i, subArray, 0, arraySize);
            resultList.add(subArray);
        }
        return resultList;
    }
    public static List<List<Word>> splitListIntoGroupsOf30(List<Word> wordList) {
        List<List<Word>> resultList = new ArrayList<>();
        int size = wordList.size();
        for (int i = 0; i < size; i += 30) {
            int end = Math.min(size, i + 30);
            resultList.add(wordList.subList(i, end));
        }
        return resultList;
    }
    public static String ChangeByteBoStringGetAndOneString(byte[]bytedata){
        try {
            List<byte[]> bytes = convertByteArrayToList(bytedata, bytedata.length);
            List<String>convertword=new ArrayList<>();
            for (byte[] bytes1:bytes){
                String s = new String(bytes1, StandardCharsets.UTF_8);
                String[] split = s.split("\\+");
                List<String>list= Arrays.stream(split).toList();
                for (String s1:list){
                    String[] split1 = s1.split("\\+");
                    List<String> list1 = Arrays.stream(split1).toList();
                    for (String s2:list1){
                        convertword.add(s2);
                    }
                }
                return convertword.get(new Random().nextInt(convertword.size()));
            }
        } catch (Exception ex) {
            System.out.println("000000000000");
        }
        return "没有例句";
    }
    public static String getRandomString(byte[] byteArray) {
        StringBuilder binaryStringBuilder = new StringBuilder();
        for (byte b : byteArray) {
            String binaryString = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
            binaryStringBuilder.append(binaryString);
        }

        String binaryString = binaryStringBuilder.toString();
        String[] splitStrings = binaryString.split("(?<=\\G.{3})");

        Random random = new Random();
        int index = random.nextInt(splitStrings.length);

        return splitStrings[index].replace(" ", "+++");
    }
    public static byte[] returntextToSpeechbyte(String text) {
        ActiveXComponent ax = null;
        byte[] audioData = null;
        try {
            ax = new ActiveXComponent("Sapi.SpFileStream");
            // 创建输出文件流
            Dispatch spFileStream = ax.getObject();

            ax = new ActiveXComponent("Sapi.SpAudioFormat");
            // 创建音频格式对象
            Dispatch spAudioFormat = ax.getObject();

            // 设置音频流格式
            Dispatch.put(spAudioFormat, "Type", new Variant(22));
            // 设置文件输出流格式
            Dispatch.putRef(spFileStream, "Format", spAudioFormat);
            // 调用输出文件流打开方法，创建一个.wav文件
            Dispatch.call(spFileStream, "Open", new Variant("./text.mp3"), new Variant(3), new Variant(true));

            ax = new ActiveXComponent("Sapi.SpVoice");
            // 创建语音朗读对象
            Dispatch spVoice = ax.getObject();
            // 设置声音对象的音频输出流为输出文件对象
            Dispatch.putRef(spVoice, "AudioOutputStream", spFileStream);
            // 设置音量 0到100
            Dispatch.put(spVoice, "Volume", new Variant(100));
            // 设置朗读速度
            Dispatch.put(spVoice, "Rate", new Variant(-2));
            // 开始朗读
            Dispatch.call(spVoice, "Speak", new Variant(text));

            // 关闭输出文件
            Dispatch.call(spFileStream, "Close");
            Dispatch.putRef(spVoice, "AudioOutputStream", null);
            // 将音频文件读取为字节数组
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new File("./text.mp3"));
            byte[] buffer = new byte[4096];
            int n;
            while ((n = audioInputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, n);
            }
            audioData = outputStream.toByteArray();

            // 关闭输入流和输出流
            outputStream.close();
            audioInputStream.close();

            spAudioFormat.safeRelease();
            spFileStream.safeRelease();
            spVoice.safeRelease();
            ax.safeRelease();

        } catch (Exception e) {
            e.printStackTrace();
        }

        return audioData;
    }
    @Test
    public void textToSpeechTest(){
        String text = "(((((((((((((((((((((((((((((((((((((((((((我是傻逼)))))))))))))))))))))))))))))))))))))))))))";
        Word rearch = wordMapper.GetWordByKey("researh");
//        ForeInformation foreInformation=new ForeInformation(rearch.getWID(),rearch.getInformation(),returntextToSpeechbyte(rearch.getExplain()),null);
        byte[] audioData = returntextToSpeechbyte(text);
        System.out.println(audioData);
        // 将音频数据保存成.wav文件
        try {
            AudioFormat format = new AudioFormat(22050, 16, 1, true, false);
            AudioInputStream audioInputStream = new AudioInputStream(new ByteArrayInputStream(audioData), format, audioData.length);
            AudioSystem.write(audioInputStream, AudioFileFormat.Type.WAVE, new File("F:\\Desktop\\output.mp3"));
            audioInputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
//        System.out.println("结果："+getSqlSession());
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        WordMapper wordMapper = sqlSession.getMapper(WordMapper.class);
//        Word sea = wordMapper.GetWordByKey("sea");
//        System.out.println(ChangeByteBoStringGetAndOneString(sea.getInformation()));
    }
    public static void clearFolder(String folderPath) {
        File folder = new File(folderPath);
        if (folder.exists() && folder.isDirectory()) {
            File[] files = folder.listFiles();
            if (files != null) {
                for (File file : files) {
                    if (file.isDirectory()) {
                        clearFolder(file.getAbsolutePath()); // �ݹ�������ļ���
                    } else {
                        file.delete(); // ɾ���ļ�
                    }
                }
            }
            System.out.println("Folder contents have been cleared.");
        } else {
            System.out.println("Folder does not exist or is not a directory.");
        }
    }
    public static List<List<String>> processFile(String fileName) {
        List<List<String>> result = new ArrayList<>();

        try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
            String line;
            while ((line = reader.readLine()) != null) {
                String[] words = line.split("                 ");
                List<String> wordList = Arrays.asList(words);
                result.add(wordList);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    public static void textToSpeech(String text) {
        ActiveXComponent ax = null;
        try {
            ax = new ActiveXComponent("Sapi.SpVoice");
            // 运行时输出语音内容
            Dispatch spVoice = ax.getObject();
            // 音量 0-100
            ax.setProperty("Volume", new Variant(100));
            // 语音朗读速度 -10 到 +10
            ax.setProperty("Rate", new Variant(-2));
            // 执行朗读
            Dispatch.call(spVoice, "Speak", new Variant(text));
            // 下面是构建文件流把生成语音文件
            ax = new ActiveXComponent("Sapi.SpFileStream");
            Dispatch spFileStream = ax.getObject();

            ax = new ActiveXComponent("Sapi.SpAudioFormat");
            Dispatch spAudioFormat = ax.getObject();

            // 设置音频流格式
            Dispatch.put(spAudioFormat, "Type", new Variant(22));
            // 设置文件输出流格式
            Dispatch.putRef(spFileStream, "Format", spAudioFormat);
            // 调用输出 文件流打开方法，创建一个.wav文件
            Dispatch.call(spFileStream, "Open", new Variant("./text.mp3"), new Variant(3), new Variant(true));
            // 设置声音对象的音频输出流为输出文件对象
            Dispatch.putRef(spVoice, "AudioOutputStream", spFileStream);
            // 设置音量 0到100
            Dispatch.put(spVoice, "Volume", new Variant(100));
            // 设置朗读速度
            Dispatch.put(spVoice, "Rate", new Variant(-2));
            // 开始朗读
            Dispatch.call(spVoice, "Speak", new Variant(text));

            // 关闭输出文件
            Dispatch.call(spFileStream, "Close");
            Dispatch.putRef(spVoice, "AudioOutputStream", null);

            spAudioFormat.safeRelease();
            spFileStream.safeRelease();
            spVoice.safeRelease();
            ax.safeRelease();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void InsertWordAndExplain(String key) throws Exception {
        Document parse = Jsoup.parse(new URL("https://www.quword.com/w/" + key ), 6000);
        Element elementById = parse.getElementById("yd-word-meaning");
        Elements li = elementById.getElementsByTag("li");
        System.out.println(li.text());
        if (!li.text().equals("")){
            System.out.println("xssxxsxs");
            Word word = new Word(key, li.text());
            wordMapper.insert(word);


            Document parse1 = Jsoup.parse(new URL("https://www.youdao.com/result?word=" + word.getWords() + "&lang=en"), 6000);
            Elements elementsByClass = parse1.getElementsByClass("sen-eng");
            List<byte[]>information1=new ArrayList<>();
            for (Element element:elementsByClass){
                information1.add(element.text().getBytes());
            }
            byte[] bytes = convertListToByteArray(information1);
            wordMapper.updat0(word.getWords(),bytes);
            Connection.Response resultImageResponse = Jsoup.connect("https://dict.youdao.com/dictvoice?audio="+word.getWords()+"&type=2").ignoreContentType(true).execute();
            InputStream in = resultImageResponse.bodyStream();
            byte[] buffer = new byte[4096];
            byte[] bytes1 = in.readAllBytes();
            int n;
            wordMapper.updat(word.getWords(),bytes1);
            in.close();
        }
    }



}

